#include "bsp_uart1.h"

uart1_buf_t uart1_buf = {0};

/**
 * @brief  uart 串口配置
 * @param  baudrate 串口波特率
 * @return 无
 */
void bsp_uart1_init(uint32_t baudrate)
{
	/* clk 配置 */
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	/* gpio 配置 */
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); // TX
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_1); // RX

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	/* uart 配置 */
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Init(USART1, &USART_InitStructure);

	/* nvic 配置 */
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	USART_SetReceiverTimeOut(USART1, 1);		   // 设置接收超时时间
	USART_ReceiverTimeOutCmd(USART1, ENABLE);	   // 使能接收超时
	USART_ITConfig(USART1, USART_IT_RTO, ENABLE);  // 使能接收超时中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能接收中断
	USART_Cmd(USART1, ENABLE);
}

/**
 * @brief  uart 串口发送数据
 * @param  *tx_buf 数组指针
 * @param  tx_len 数据长度
 * @return 无
 */
void bsp_uart1_tx(uint8_t *tx_buf, uint16_t tx_len)
{
	for (uint16_t i = 0; i < tx_len; i++)
	{
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) // 等待发送完成
			;
		USART_SendData(USART1, tx_buf[i]); // 发送字节
	}
}

/**
 * @brief  uart 串口中断，保存接收的数据，并在接收到第一个数据时开启定时器计数
 * @param  无
 * @return 无
 */
void USART1_IRQHandler(void)
{
	if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
	{
		if (uart1_buf.rx_state != RX_FINISH)
		{
			if (uart1_buf.rx_state == RX_WAIT)
				uart1_buf.rx_state = RX_START;								// 接收一帧数据的第一位，开始计时
			uart1_buf.rxbuf[uart1_buf.rxlen++] = USART_ReceiveData(USART1); // 保存数据
		}

		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}

	if (USART_GetITStatus(USART1, USART_IT_RTO) != RESET) // 接收超时中断
	{
		uart1_buf.rx_state = RX_FINISH;
		USART_ClearITPendingBit(USART1, USART_IT_RTO);
	}
}

int fputc(int ch, FILE *f)
{
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
		;
	USART_SendData(USART1, (uint16_t)ch);

	return ch;
}
